public class EdgeData {

        /**The capacity of the edge*/
        private int m_capacity; 

        /**The flow on the edge*/
        private int m_flow; 

        /**These variables may need in residual graph  */
        
        /**The capacity in the forward edge*/
        private int m_Cf;  

        /**The capacity in the backward edge*/
        private int m_Cb;   
        
        /**m_Cf + m_Cb = m_capacity. 
         * m_Cb = m_flow; 
         * */
        /**
         * Returns the maximum capacity minus the current flow.
         * 
         * @return int Available capacity
         */
        public int getAvailable() {
                return this.m_capacity - m_flow;
        }
        
        public EdgeData()
        {
                this(new Double(0));
        };
        
        
        public EdgeData(Double capacity) {
                // TODO Auto-generated constructor stub
                this(capacity.intValue());
        };
        
        public EdgeData(int capacity) {
        	if(m_capacity<m_flow || m_flow<0 || m_capacity<0)
                throw new IndexOutOfBoundsException();
                m_flow = 0;     
                m_capacity = capacity;
                m_Cf = m_capacity - m_flow;
                m_Cb =  m_flow;
        };
        
        /**
         * Initialize EdgeData with custom values.
         * 
         * @param capacity The maximum flow an edge can carry.
         * @param flow The current flow an edge is carrying.
         * @throws Exception If provided values are out of bounds.
         */
        public EdgeData(int capacity, int flow) throws Exception{
                if(capacity<flow || flow<0 || capacity<0)
                        throw new IndexOutOfBoundsException();
                this.m_capacity = capacity;
                this.m_flow = flow;
        }
        
        public int getForwardCapacity()
        {
                this.m_Cf = this.m_capacity - this.m_flow;
                return m_Cf;
        }
        
        public int getBackwardCapacity()
        {
                this.m_Cb =  this.m_flow;
                return this.m_Cb;
        }


        public int getCapacity()
        {
                return this.m_capacity;
        }
        
        public int getFlow()
        {
                return this.m_flow;
        }
        
        /**
         * 
         * @param value, increase the m_flow by value
         * @return the amount of flow that is decreased * 
         * If the value exceeds the capacity of a edge, increase the flow to capacity
         */
        public int increaseFlow(int value)
        {
                int increase = value;
                if(value > m_Cf)
                {
                        increase = m_Cf;
                        m_flow = m_capacity;
                }
                else
                {
                        m_flow += value;
                }
                m_Cb = m_flow;
                m_Cf = m_capacity - m_Cb;
                return increase;
        }
        
        /**
         * 
         * @param value, decrease the m_flow by value
         * @return the amount of flow that is decreased
         * If the value exceeds the flow, decrease flow value to zero.
         */
        public int decreaseFlow(int value)
        {
                int decrease = value;
                if((m_flow - value) < 0)
                {
                        decrease = m_flow;
                        m_flow = 0;
                }
                else
                        m_flow -= value;
                m_Cb = m_flow;
                m_Cf = m_capacity - m_Cb;
                return decrease;
        }
        /**
         * Sets the current flow of this edge.
         * 
         * @param flow New flow value this edge will carry.
         * @throws Exception If provided flow is out of bounds.
         */
        public void setFlow(int flow) throws Exception{
                if(this.m_capacity<m_flow || m_flow<0)
                        throw new IndexOutOfBoundsException();
                this.m_flow = flow;
        }
        
        
}
